package com.study.cloud.gateway.core.filter;

import com.study.cloud.gateway.common.rule.Rule;
import com.study.cloud.gateway.core.context.GatewayContext;
import com.study.cloud.gateway.core.filter.route.RouterFilter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author wangwancheng
 * @create 2025/7/20 15:29
 */
@Slf4j
public class GatewayFilterChainFactory implements FilterChainFactory{

    private Map<String,FilterInterface> filterInterfaceMap = new ConcurrentHashMap<>();

    /**单例模式**/
    private static class SingletonHolder {
        private static final GatewayFilterChainFactory INSTANCE = new GatewayFilterChainFactory();
    }
    public static GatewayFilterChainFactory getInstance() {
        return SingletonHolder.INSTANCE;
    }
    /**单例模式**/
    private GatewayFilterChainFactory(){
        //构造方法中加载过滤器
        //spi方式加载
        ServiceLoader<FilterInterface> filterInterfaces = ServiceLoader.load(FilterInterface.class);
        for (FilterInterface filterInterface : filterInterfaces){
            Filter filter = filterInterface.getClass().getAnnotation(Filter.class);
            if (filter == null){
                continue;
            }
            log.info("加载过滤器：" + filter.name() + "，id：" + filter.id() + "，order：" + filter.order());
            String filterId = filter.id();
            if (StringUtils.isBlank(filterId)){
                filterId = filterInterface.getClass().getName();
            }
            if (filterInterfaceMap.containsKey(filterId)){
                log.error("过滤器id重复：" + filterId);
                throw new RuntimeException("过滤器id重复：" + filterId);
            }else{
                filterInterfaceMap.put(filterId,filterInterface);
            }
        }
    }
    @Override
    public GatewayFilterChain build(GatewayContext context) throws Exception {
        GatewayFilterChain chain = new GatewayFilterChain();
        List<FilterInterface> filterInterfaceList = new ArrayList<>();
        Rule rule = context.getRule();
        if (rule != null){
            Set<Rule.FilterConfig> filterConfigs = rule.getFilterConfigs();
            for (Rule.FilterConfig filterConfig : filterConfigs){
                if (filterConfig == null){
                    continue;
                }
                String filterId = filterConfig.getId();
                FilterInterface filterInterface = getFilterInfo(filterId);
                if (StringUtils.isNotBlank(filterId) && filterInterface != null){
                    filterInterfaceList.add(filterInterface);
                }
            }
            //路由发送请求的过滤器
            //TODO 路由过滤器 这个过滤器要放到最后
            filterInterfaceList.add(new RouterFilter());

            //排序
            filterInterfaceList.sort(Comparator.comparing(FilterInterface::getOrder));
            //放入 过滤器链中
            chain.addFilterList(filterInterfaceList);
        }
        return chain;
    }

    @Override
    public FilterInterface getFilterInfo(String filterId) throws Exception {
        return filterInterfaceMap.get(filterId);
    }
}
